package com.tina.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tina.constant.ShopCode;
import com.tina.entity.AlipayBean;
import com.tina.entity.Flowers;
import com.tina.entity.Orders;
import com.tina.exception.CastException;
import com.tina.exception.CustomerException;
import com.tina.mapper.OrdersMapper;
import com.tina.service.IFlowersService;
import com.tina.service.IOrdersService;
import com.tina.util.AliPayUtil;
import com.tina.util.DateUtils;
import com.tina.util.IDWorker;
import com.tina.util.MqUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 订单表 服务实现类
 * </p>
 *
 * @author Tina
 * @since 2020-10-26
 */
@Service
@Slf4j
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements IOrdersService {

    @Autowired
    private OrdersMapper ordersMapper;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Autowired
    private IFlowersService flowersService;

    //需要注入bean才能使用自动注入不然启动会报的
    @Autowired
    private IDWorker idWorker;

    @Value("${mq.order.topic}")
    private String orderTopic;
    @Value("${mq.order.tag.cancel}")
    private String cancelTag;

    @Value("${mq.payTimeOutMsg.topic}")
    private String payTimeOutMsg;

    @Value("${mq.payTimeOutMsg.tag.success}")
    private String pay_time_out_cancel;

    @Autowired
    private MqUtil mqUtil;

    @Resource
    private AliPayUtil aliPayUtil;

    @Override
    public Integer insertOrders(Orders orders) {
        //rocketMQTemplate.
        return ordersMapper.insert(orders);
    }

    @Override
    public Integer editOrders(Orders orders) {
        UpdateWrapper updateWrapper = new UpdateWrapper();
        updateWrapper.eq("order_id", orders.getOrderId());
        return ordersMapper.update(orders, updateWrapper);
    }

    @Override
    public List<Orders> selectOrders(Orders orders) {
        QueryWrapper<Orders> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("add_time");
        return ordersMapper.selectList(queryWrapper);
    }

    @Override
    public Integer ordersCountNum() {
        return ordersMapper.selectCount(new QueryWrapper());
    }

    @Override
    public Orders selectOrdersById(String orderId) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("order_id", orderId);
        return ordersMapper.selectOne(queryWrapper);
    }

    /**
     * 下单
     *
     * @param orders
     * @return
     */
    @Override
    public String confirmOrder(Orders orders) {

        //生成预订单 计算总金额
        orders.setStatus(ShopCode.SHOP_USER_PENDING_PAYMENT.getCode());
        orders.setAddTime(DateUtils.getTime());
        orders.setOrderId(String.valueOf(idWorker.nextId()));
        orders.setTotalAmount(BigDecimal.valueOf(orders.getNumber() * Double.valueOf(String.valueOf(orders.getSellPrice()))));
        insertOrders(orders);
        try {

            //扣减库存
            Flowers flowers = new Flowers();
            flowers.setStock(orders.getNumber());
            flowers.setId(orders.getFlowersId());
            flowersService.reduceGoodsNum(flowers);
            //校验证当前订单是否已支付
            checkOrderPay(orders.getOrderId());
            //确认订单
            Orders goods = new Orders();
            goods.setOrderId(orders.getOrderId());
            updateOrderStatus(goods);
            // 模拟异常抛出
            // CastException.cast(ShopCode.SHOP_FAIL);
            //返回成功状态
            return orders.getOrderId();
        } catch (Exception e) {
            //1.确认订单失败,发送消息
            try {
                mqUtil.sendMsg(orderTopic, cancelTag, orders.getOrderId().toString(), JSON.toJSONString(orders));
            } catch (Exception exception) {
                exception.printStackTrace();
            }
            //2.返回订单确认失败消息
            e.printStackTrace();
            return e.getMessage();
        }

    }

    /**
     * 生成预订单二维码
     *
     * @param orders
     * @return
     */
    @Transactional
    @Override
    public String orderFrom(Orders orders) {
        try {
            //生成预订单 计算总金额
            orders.setStatus(ShopCode.SHOP_USER_PENDING_PAYMENT.getCode());
            orders.setAddTime(DateUtils.getTime());
            orders.setOrderId(String.valueOf(idWorker.nextId()));
            orders.setTotalAmount(BigDecimal.valueOf(orders.getNumber() * Double.valueOf(String.valueOf(orders.getSellPrice()))));
            String codePay = aliPayUtil.codePay(orders.getOrderId(), orders.getTotalAmount(), orders.getTitle());
            orders.setCodePayUrl(codePay);
            insertOrders(orders);
            //扣减库存
            Flowers flowers = new Flowers();
            flowers.setStock(orders.getNumber());
            flowers.setId(orders.getFlowersId());
            flowersService.reduceGoodsNum(flowers);
            mqUtil.sendAffairMsg(payTimeOutMsg, pay_time_out_cancel, orders.getOrderId().toString(), JSON.toJSONString(orders));
            return codePay;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 支付宝二维码支付
     *
     * @param orders
     * @return
     */
    @Override
    public String codePay(Orders orders) {
        return null;
    }

    /**
     * 支付
     *
     * @param orderId
     * @throws Exception
     */
    @Override
    public String pay(String orderId) {
        try {
            //1、查询订单
            Orders orders = selectOrdersById(orderId);
            //2. 调用支付宝
            AlipayBean alipayBean = new AlipayBean();
            alipayBean.setOut_trade_no(orders.getOrderId());
            alipayBean.setSubject(orders.getTitle());
            alipayBean.setTotal_amount(String.valueOf(orders.getTotalAmount()));
            String pay = aliPayUtil.pay(alipayBean);
            log.info("pay->{}", pay);

            return pay;
        } catch (Exception e) {
            e.printStackTrace();
            CastException.cast(ShopCode.SHOP_PAYMENT_PAY_ERROR);
            return null;
        }
    }

    /**
     * 校验证订单是否有效果时间内
     *
     * @param orderId
     * @return
     */
    @Override
    public void checkOrderTime(String orderId) {
        Orders orders = selectOrdersById(orderId);
        if (StringUtils.isEmpty(orders)) {
            CastException.cast(ShopCode.SHOP_ORDER_NOT);
        }
        if (DateUtils.getDateMin(DateUtils.parseDate(orders.getAddTime()), new Date()) > 15) {
            CastException.cast(ShopCode.SHOP_ORDER_INVALID);
        }
        log.info(orderId + " 订单还在有效时间内");
    }

    /**
     * 校验证订单是否已支付
     *
     * @param orderId
     * @return
     */
    @Override
    public void checkOrderPay(String orderId) throws CustomerException {
        Orders orders = selectOrdersById(orderId);
        if (StringUtils.isEmpty(orders)) {
            CastException.cast(ShopCode.SHOP_ORDER_NOT);
        }
        if (orders.getStatus().equals(ShopCode.SHOP_ORDER_PAY_STATUS_IS_PAY.getCode())) {
            CastException.cast(ShopCode.SHOP_ORDER_PAY_STATUS_IS_PAY);
        }
        log.info(orderId + " 订单未支付");
    }

    /**
     * 校验当前订单
     *
     * @return
     */
    @Override
    public void checkOrder(String orderId) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("order_id", orderId);
        Orders orders = ordersMapper.selectOne(queryWrapper);
        if (StringUtils.isEmpty(orders)) {
            CastException.cast(ShopCode.SHOP_ORDER_NOT);
        }
        if (orders.getStatus().equals(ShopCode.SHOP_ORDER_PAY_STATUS_IS_PAY.getCode())) {
            CastException.cast(ShopCode.SHOP_ORDER_PAY_STATUS_IS_PAY);
        }
        if (orders.getStatus().equals(ShopCode.SHOP_ORDER_CANCEL.getCode())) {
            CastException.cast(ShopCode.SHOP_ORDER_CANCEL);
        }
        Date date = DateUtils.parseDate(orders.getAddTime());
        log.info("date->{}", date);
        long dateMin = DateUtils.getDateMin(date, DateUtils.getNowDate());
        if (dateMin > 15) {
            CastException.cast(ShopCode.SHOP_ORDER_INVALID);
        }
        log.info("当前:" + orderId + " 校验证成功");
    }

    /**
     * 确认订单
     *
     * @param orders
     */
    private void updateOrderStatus(Orders orders) {
        orders.setEditTime(DateUtils.getTime());
        orders.setPaymentTime(DateUtils.getTime());
        orders.setStatus(ShopCode.SHOP_USER_PENDING_PAYMENT.getCode());
        UpdateWrapper updateWrapper = new UpdateWrapper();
        updateWrapper.eq("order_id", orders.getOrderId());
        Integer r = ordersMapper.update(orders, updateWrapper);
        if (r <= 0) {
            CastException.cast(ShopCode.SHOP_ORDER_CONFIRM_FAIL);
        }
        log.info(orders.getOrderId() + " 订单确定成功");
    }


}
